package main

import (
	"container/list"
	"context"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/hgslb/base"
	"gitee.com/hgslb/infra"
)

type container struct {
	appList *list.List
	ctx     context.Context
	stop    context.CancelFunc
}

func (app *container) Start() error {
	conf := "../config/gslb.yaml"
	base.GslgBase.Init(conf)
	base.GslbGeoDb.Start()
	infra.Start()

	app.appList = list.New()
	app.ctx, app.stop = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	base.GslbLog.Info("AppLife startted")
	return nil
}

func (app *container) Wait() {
	<-app.ctx.Done()
	app.stop()
	base.GslbLog.Info("Shutdown Server ...")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	for app.appList.Len() > 0 {
		front := app.appList.Front()
		app.appList.Remove(front)
		serv := front.Value.(GSLBServer)
		base.GslbLog.Infof("Server %s stopping.......", serv.GetName())
		serv.Stop(&ctx)
		base.GslbLog.Infof("Server %s shutdown", serv.GetName())
	}
}

func (app *container) Stop() {
	base.GslbGeoDb.Stop()
	infra.Stop()
}

func main() {
	app := &container{}
	app.Start()

	dnsSrv := &dnsServer{}
	err := dnsSrv.Start(&app.ctx)
	if err != nil {
		panic(err)
	}

	app.appList.PushBack(dnsSrv)

	app.Wait()
	app.Stop()
}
